import { createOverlay, FrameworkDelegate } from '@ibiz/stencil-util';
import { DrawerOptions } from '../../interface';

/**
 * 抽屉控制器
 *
 * @author chitanda
 * @date 2021-06-01 11:06:26
 * @export
 * @class DrawerController
 */
export class DrawerController {
  // 第三方技术绘制代理
  protected static delegate?: FrameworkDelegate;

  /**
   * 导航Bar
   *
   * @author chitanda
   * @date 2021-06-02 16:06:53
   * @static
   * @type {HTMLIbzDrawerExpElement}
   */
  protected static $exp: HTMLIbzDrawerExpElement;
  static get exp(): HTMLIbzDrawerExpElement {
    return this.$exp;
  }

  /**
   * 安装
   *
   * @author chitanda
   * @date 2021-04-05 14:04:35
   * @static
   * @param {FrameworkDelegate} [delegate] 界面渲染代理
   */
  static install(delegate?: FrameworkDelegate): void {
    this.delegate = delegate;
    this.$exp = document.createElement('ibz-drawer-exp');
    document.body.appendChild(this.$exp);
  }

  /**
   * 列表数据缓存
   *
   * @author fangZhiHao
   * @date 2023-03-07 22:03:42
   * @static
   */
  protected static drawerList: Map<string, HTMLIbzDrawerElement> = new Map()

  /**
   * 打开顶级飘窗
   *
   * @author chitanda
   * @date 2021-06-01 11:06:20
   * @static
   * @param {DrawerOptions} opts
   * @return {*}  {Promise<HTMLIbzDrawerElement>}
   */
  static async present(opts: DrawerOptions): Promise<HTMLIbzDrawerElement> {
    const { id, beforeDismiss } = opts;
    this.$exp.hiddenAll();
    if (id && this.drawerList.has(id)) {
      const cacheRef = this.drawerList.get(id);
      setTimeout(() => {
        cacheRef.show();
      })
      return cacheRef;
    }
    const ref = await createOverlay('ibz-drawer', { delegate: this.delegate, beforeDismiss }) as HTMLIbzDrawerElement;
    Object.assign(ref, opts);
    if (id) {
      this.drawerList.set(id, ref);
      ref.onDidDismiss().then(() => {
        this.drawerList.delete(id);
      });
    }
    await ref.present();
    return ref;
  }

  /**
   * 关闭指定飘窗组件
   *
   * @author chitanda
   * @date 2021-06-01 13:06:08
   * @static
   * @param {HTMLIbzDrawerElement} ref
   * @return {*}  {Promise<any>}
   */
  static async dismiss(ref: HTMLIbzDrawerElement): Promise<any> {
    if (ref) {
      const data = await ref.onDidDismiss();
      ref.remove();
      return data;
    }
  }
}
